//////////////////////////////////////////////////////////////////////////

#ifndef _CONNECTION_H_
#define _CONNECTION_H_

//////////////////////////////////////////////////////////////////////////

#ifndef _ICONNECTION_H_
#include "iconnection.h"
#endif

#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>

//////////////////////////////////////////////////////////////////////////

/** [Utility type]: a shared pointer to tcp::socket */
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> TCPSocketPtr;

//////////////////////////////////////////////////////////////////////////


/** Base network connection for client and server
*   It has ID and a buffer for received TCP packets
*
*  @author   Pasechnik Roman
*  @since    Jun 29th, 2009
*  @updated  Jan 18th, 2010
*/
class Connection : public virtual IConnection
{
//////////////////////////////////////////////////////////////////////////

public:

//////////////////////////////////////////////////////////////////////////


    /** Constructor */
    Connection( const TCPSocketPtr& _TCPSocket );


    /** Destructor */
    virtual ~Connection();


//////////////////////////////////////////////////////////////////////////


    /** Sends TCP */
    virtual void SendTCP( const NetworkPacket& _data );


    /** Sends UDP */
    virtual void SendUDP( const NetworkPacket& _data ) = 0;



//////////////////////////////////////////////////////////////////////////


    /** Gets received TCP data */
    virtual const NetworkPacket& GetTCP() const;


    /** Gets received UDP data */
    virtual const NetworkPacket& GetUDP() const;


//////////////////////////////////////////////////////////////////////////


    /** Tells if connection is connected */
    virtual bool IsConnected() const;


//////////////////////////////////////////////////////////////////////////

protected:

//////////////////////////////////////////////////////////////////////////


    /** Start receive TCP packets */
    void StartReceiveTCP();


//////////////////////////////////////////////////////////////////////////


    /** Max buffer size for incoming network packets */
    enum { MAX_BUFFER_SIZE = 1024 };


    /** TCP socket */
    TCPSocketPtr m_TCPSocket;


    /** Received UDP packet */
    NetworkPacket m_UDPRecvPacket;


//////////////////////////////////////////////////////////////////////////

private:

//////////////////////////////////////////////////////////////////////////


    /** Handle sent TCP packet */
    void HandleSendTCP( const boost::system::error_code& _error,
                        size_t _bytesTransferred );


    /** Handle received TCP packet */
    void HandleRecvTCP( const boost::system::error_code& _error,
                        size_t _bytesTransferred );


    /** Disconnect handler */
    void HandleDisconnect();


//////////////////////////////////////////////////////////////////////////


    /** Received TCP packet */
    NetworkPacket m_TCPRecvPacket;


    /** Buffer for received TCP data */
    char m_RecvBufferTCP[MAX_BUFFER_SIZE];


//////////////////////////////////////////////////////////////////////////
};



//////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////
